﻿#define _CRT_SECURE_NO_WARNINGS 1



//C语言中有几个较常用的内存函数，它们分别是：
// memcpy()、 memmove()、 memcmp()、 memset()
//注意一个点：在使用他们之前，得先引入它们的头文件<string.h>

//memcpy的使用
//原型：void * memcpy ( void * destination, const void * source, size_t num ); 
//destination:是指向目标对象的空间的指针
//source:是指待拷贝对象空间的指针


#include<stdio.h>
#include<string.h>
//int main()
//{
//	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 }; //拷贝的数据
//
//	int arr2[10] = { 0 }; //待拷贝的数组
//
//	//40的缘由：因为我要拷贝的是10个整形数据，而一个整型类型的大小占4个字节
//	memcpy(arr2, arr1, 40);
//
//
//	for (int i = 0; i < 10; i++)
//	{
//		printf("%d ",arr2[i]);
//	}
//
//	return 0;
//}


//memcpy函数的模拟实现

//void* my_memcpy(void* dest, const void* src, size_t num)
//{
//	void* start = dest;
//	while (num--)
//	{
//		*(char*)dest = *(char*)src;
//		(char*)src = (char*)src + 1;
//		(char*)dest = (char*)dest + 1;
//	}
//
//	return start;
//}
//
//int main()
//{
//	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 }; //源数据
//
//	int arr2[10] = { 0 };
//
//	my_memcpy(arr2, arr1, 40);
//
//	for (int i = 0; i < 10; i++)
//	{
//		printf("%d ", arr2[i]);
//	}
//
//	return 0;
//}

//struct S
//{
//	int age;
//	char name[20];
//};
//
//int main()
//{
//	struct S s1 = { 10,"张三" };
//	struct S s2 = { 0 };
//
//	struct S* p1 = &s1, * p2 = &s2;
//
//	my_memcpy(p2,p1,sizeof(s1));
//
//	printf("%d %s\n",s2.age, s2.name);
//	return 0;
//}



//memmove函数
//再先讲memmove函数时，先讲一下这个函数的重要性
//大胆设想一下，如果我用memcpy函数，做这么一件事：
//将目标数组的第0~3的元素拷贝到第3~6的元素中去，会发生什么效果？

//虽然以下代码能在VS中编译成功，但这并不意味着再别的编译器上这个代码就跑的过去。
//实际上，如果我们要在该数组或者别的数据类型上修改自身成员的值时，用memcpy()函数是个未定义的行为

//int main()
//{
//	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
//
//	memcpy(arr1+3,arr1,16);
//
//	for (int i = 0; i < 10; i++)
//	{
//		printf("%d ",arr1[i]);
//	}
//
//	return 0;
//}

//那我们怎么解决这个问题呢？
//用memmove()函数即可。
//memmove函数的原型：void * memmove ( void * destination, const void * source, size_t num );(跟memcpy的形参是一致的)
//int main()
//{
//	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
//
//	memmove(arr1+3,arr1,16);
//
//	for (int i = 0; i < 10; i++)
//	{
//		printf("%d ",arr1[i]);
//	}
//
//	return 0;
//}

//int main()
//{
//	char arr1[30] = "I love learning C!";
//	
//	memmove(arr1 + 16, arr1 + 2, 4);
//
//	printf("%s\n", arr1);
//	return 0;
//}

//memmove()函数的模拟实现
void* my_memmove(void* dest, const void* src, size_t num)
{
	void* start = dest;

	if ((dest < src) || ((char*)src + num) <= (char*)dest)
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;

			(char*)src = (char*)src + 1;
			(char*)dest = (char*)dest + 1;
		}
	}
	else
	{
		(char*)src = (char*)src + num - 1;
		(char*)dest = (char*)dest + num - 1;
		while (num--)
		{
			*(char*)dest = *(char*)src;
			(char*)src = (char*)src - 1;
			(char*)dest = (char*)dest - 1;
		}
		
	}

	return dest;
}
//
//int main()
//{
//	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
//
//	my_memmove(arr1 + 3, arr1, 16);
//
//	for (int i = 0; i < 10; i++)
//	{
//		printf("%d ", arr1[i]);
//	}
//
//	return 0;
//}


//memset()函数
//memset是⽤来设置内存的，将内存中的值以字节为单位设置成想要的内容。
//memset函数的原型：void * memset ( void * ptr, int value, size_t num );
//参数解释： 
//			ptr：指向待操作的空间
//			value：修改时填充的值，就是value的大小
//			num：设置修多少个字节数


//int main()
//{
//	char arr[] = "I love learning C!";
//
//	memset(arr, 'Y', 1);
//
//	printf("%s\n",arr);
//
//	return 0;
//}


//memset函数的实例演示
//#include<stdio.h>
//#include<string.h>
//
//struct Consumer
//{
//	char name[20];
//	int age;
//	float weight;
//};
//
//int main()
//{
//	struct Consumer c1 = { "张三", 32 ,150.8 };
//	struct Consumer* p_str = &c1;
//
//	memset(p_str,'x',4);//这里填4，是因为中文在C语言中占2个字节
//	printf("姓名  年龄  体重\n");
//	printf("%s   %d  %.2f", c1.name,c1.age,c1.weight);
//
//	return 0;
//}

//memset函数的模拟实现
//void* my_memset(void* ptr, int value, size_t num)
//{
//	void* start = ptr;
//
//	while (num--)
//	{
//		*(char*)ptr = value;
//		(char*)ptr = (char*)ptr + 1;
//	}
//
//	return start;
//}

//memset的模拟实现

//之前写错的代码
//void* my_memset(void* obj, int value, size_t num)
//{
//	void* start = obj;
//	while (num--)
//	{
//		*(int*)obj = value;
//		(char*)obj = (char*)obj + 1;
//	}
//
//	return start;
//}

//void* my_memset(void* obj, int value, size_t num)
//{
//	void* start = obj;
//	while (num--)
//	{
//		*(char*)obj =value;
//		(char*)obj = (char*)obj + 1;
//	}
//	
//	return start;
//}
//
//int main()
//{
//	char str[] = "hello world";
//	my_memset(str, 'x', 5);
//	printf(str);
//	return 0;
//}


//memcmp()函数
//memcmp函数的原型：int memcmp(const char* p1, const char* p2, size_t num)

//int main()
//{
//	char arr1[] = "I love learning C!";
//	char arr2[] = "I like learning C!";
//
//	int ret1 = memcmp(arr1, arr2, 3);
//	int ret2 = memcmp(arr1, arr2, 5);
//	int ret3 = memcmp(arr1, arr2, 10);
//	
//	//ret1 = ?   ret2 = ?   ret3 = ?
//	printf("ret1 = %d  ret2 = %d  ret3 = %d\n",ret1,ret2,ret3);
//
//	return 0;
//}



int my_memcmp(const void* p1, const void* p2, size_t num)
{
	int flag = 0;

	while (num--)
	{
		if (*(char*)p1 != *(char*)p2)
		{
			if (*(char*)p1 > *(char*)p2)
			{
				flag = 1;
				return flag;
			}
			else
			{
				flag = -1;
				return flag;
			}
		}
		(char*)p1 = (char*)p1 + 1;
		(char*)p2 = (char*)p2 + 1;

	}

	if (!flag)
	{
		return flag;
	}
}


int main()
{
	int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int arr2[10] = { 1,2,3,4,5,6,7,8,9,10 };

	int ret = my_memcmp(arr1, arr2, sizeof(arr1) / sizeof(arr1[0]));

	if (ret != 0)
	{
		printf("These arrays are different!\n");
	}
	else
	{
		printf("These arrays are similar!\n");
	}

	return 0;
}


//int main()
//{
//	char arr1[] = "I love learning C!";
//	char arr2[] = "I like learning C!";
//
//	int ret1 = my_memcmp(arr1, arr2, 3);
//	int ret2 = my_memcmp(arr1, arr2, 5);
//	int ret3 = my_memcmp(arr1, arr2, 10);
//
//	
//	printf("ret1 = %d  ret2 = %d  ret3 = %d\n", ret1, ret2, ret3);
//
//	return 0;
//}

